package object2;

/**
 * 多态注意事项
 */
public class PolyDetail {

    public static void main(String[] args) {

        /*
            多态的前提是两个对象(类)存在继承关系

            多态的向上转型：
            1)本质：父类的引用指向子类的对象
            2)语法：父类类型 引用名 = new 子类类型();
            3)特点：编译类型看左边，运行类型看右边
                   可以调用父类中的所有成员(须遵守访问权限)
                   不能调用子类中特有成员

            多态的向下转型：
            1)语法：子类类型 引用名 = (子类类型) 父类引用
            2)只能强转父类的引用，不能强转父类的对象
            3)要求父类的引用必须指向的是当前目标类型的对象
            4)当向下转型后，可以调用子类类型中所有的成员
         */

        //向上转型：父类的引用指向子类的对象
        PolyAnimals animal = new PolyCat();
        Object obj  = new Cat();//也可以，Object是Cat的父类

        //可以调用父类中所有成员，但是不能调用子类特有成员。因为在编译阶段，能调用哪些成员是由编译类型来决定的
//        animal.catchMouse();

        //最终运行效果看子类(运行类型)的具体实现，即调用方法时，按照从子类(运行类型)开始查找方法
        animal.eat();//猫吃鱼
        animal.sleep();//睡...

        //向下转型：强转父类的引用为子类，再让子类对象指向它
        //此时cat编译类型为PolyCat，运行类型为PolyCat
        PolyCat cat = (PolyCat) animal;
        cat.catchMouse();//猫抓老鼠

        //要求父类的引用必须指向的是当前目标类型的对象
        //PolyDog dog = (PolyDog) animal;//不可以转了，animal原先指向PolyCat，只能向下转为PolyCat
        System.out.println("ok~~");

    }
}

class PolyAnimals {

    String name = "动物";

    int age = 10;

    public void sleep() {
        System.out.println("睡...");
    }

    public void run() {
        System.out.println("跑...");
    }

    public void eat() {
        System.out.println("吃...");
    }

    public void show() {
        System.out.println("hello，你好...");
    }
}

class PolyCat extends PolyAnimals {

    public void eat() {//方法重写
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {//Cat特有方法
        System.out.println("猫抓老鼠");
    }
}

class PolyDog extends PolyAnimals {

}
